﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Net;

namespace Arbalest.Web.Helpers
{
    public class NetworkHelper : BaseHelper
    {
        public static bool IsAddressOnSubnet(IPAddress address, IPAddress subnet, IPAddress subnetMask)
        {
            //http://www.cisco.com/web/about/ac123/ac147/archived_issues/ipj_9-1/ip_addresses.html

            byte[] addressBytes = address.GetAddressBytes();
            byte[] subnetMaskBytes = subnetMask.GetAddressBytes();
            byte[] maskedAddressBytes = new byte[addressBytes.Length];

            for (int i = 0; i < maskedAddressBytes.Length; ++i)
                maskedAddressBytes[i] = (byte)(addressBytes[i] & subnetMaskBytes[i]);

            IPAddress maskedIPAddress = new IPAddress(maskedAddressBytes);

            bool equal = subnet.Equals(maskedIPAddress);

            return equal;
        }

        public static bool IsPrivateAddress(IPAddress address)
        {
            IPAddress subnetA = IPAddress.Parse("10.0.0.0");
            IPAddress subnetB = IPAddress.Parse("172.16.0.0");
            IPAddress subnetC = IPAddress.Parse("192.168.0.0");

            IPAddress subnetMaskA = IPAddress.Parse("255.0.0.0");
            IPAddress subnetMaskB = IPAddress.Parse("255.240.0.0");
            IPAddress subnetMaskC = IPAddress.Parse("255.255.0.0");

            //RFC1918 name	IP address range	            number of addresses	classful description	        largest CIDR block (subnet mask)	host id size	mask bits
            //24-bit block	10.0.0.0    - 10.255.255.255	16,777,216	        single          class A network	10.0.0.0/8      (255.0.0.0)	        24 bits	        8 bits
            //20-bit block	172.16.0.0  - 172.31.255.255	1,048,576	        16 contiguous   class B network	172.16.0.0/12   (255.240.0.0)	    20 bits	        12 bits
            //16-bit block	192.168.0.0 - 192.168.255.255	65,536	            256 contiguous  class C network	192.168.0.0/16  (255.255.0.0)	    16 bits	        16 bits
            return (
                IPAddress.IsLoopback(address) || 
                IsAddressOnSubnet(address, subnetA, subnetMaskA) || 
                IsAddressOnSubnet(address, subnetB, subnetMaskB) ||
                IsAddressOnSubnet(address, subnetC, subnetMaskC)); 
        }

    }
}